#ifndef _UI_ATTRIBUTE_H_
#define _UI_ATTRIBUTE_H_

#include <Util/Basic/TypeMap.h>

#include <Util/Basic/Ptr.h>

#include <qobject.h>
#include <qtoolbox.h>

#include <map>

namespace Util {
	namespace Engine {
		class SObj;
		class Component;
	}
	namespace QT {
		class RawAPI_OGLW;
	}
}


namespace Ui {
	class Grid;

	class Attribute final {
	protected:
		Attribute();

	public:
		static Attribute * GetInstance() {
			static Attribute instance;
			return &instance;
		}

	public:
		void Init(QToolBox * tbox, Util::QT::RawAPI_OGLW * pOGLW);
		void SetSObj(Util::Basic::Ptr<Util::Engine::SObj> sobj);
		const Util::Basic::Ptr<Util::Engine::SObj> GetCurSObj() const { return curSObj.lock(); }
		template<typename T, typename = std::enable_if_t<std::is_base_of_v<Util::Engine::Component, T>>>
		void SetCurCmpt() {
			auto target = componentType2item.find(typeid(T));
			if (target == componentType2item.end())
				return;

			tbox->setCurrentWidget(target->second);
		}

	private:
		void AddController(Util::Basic::Ptr<Util::Engine::SObj> sobj);

	private:
		class ComponentVisitor;
		friend class ComponentVisitor;

		QToolBox * tbox;

		Util::Basic::TypeMap<QWidget *> componentType2item;
		std::map<QWidget *, Util::Basic::Ptr<Grid>> item2grid;

		Util::Basic::Ptr<ComponentVisitor> visitor;

		Util::Basic::WPtr<Util::Engine::SObj> curSObj;

		Util::QT::RawAPI_OGLW * pOGLW;
	};
}

#endif//!_UI_ATTRIBUTE_H_
